home *** CD-ROM | disk | FTP | other *** search
- ' The MultiplierEx custom control shows how you can implement
- ' client-side JavaScript routines and associate them with a control
-
- ' This source code is very similar to the Multiplier control, except that
- ' the Button class now refers to a nested class that renders the
- ' necessary attribute for the button.
-
- Imports System.ComponentModel
- Imports System.Web.UI
- Imports System.Web.UI.WebControls
-
- <ToolboxData("<{0}:MultiplierEx runat=server></{0}:MultiplierEx>")> _
- Public Class MultiplierEx
- Inherits System.Web.UI.WebControls.WebControl
- Implements INamingContainer
-
- ' These variables hold the control.
- Dim txtFirst As TextBox
- Dim txtSecond As TextBox
- Dim txtResult As TextBox
- Dim WithEvents btnEval As Button
-
- Sub New()
- MyBase.New()
- Me.Width = Unit.Pixel(200)
- End Sub
-
- ' ALl controls that rely on client-side features should implement this property
-
- Property EnableClientScript() As Boolean
- Get
- Dim o As Object = Me.ViewState("EnableClientScript")
- If o Is Nothing Then
- Return True
- Else
- Return CBool(o)
- End If
- End Get
- Set(ByVal Value As Boolean)
- Me.ViewState("EnableClientScript") = Value
- End Set
- End Property
-
- ' this code is very similar to the code in Multiplier control
-
- Protected Overrides Sub CreateChildControls()
- 'Create all child controls .
- txtFirst = New TextBox()
- txtSecond = New TextBox()
- btnEval = New Button()
- txtResult = New TextBox()
- Dim lblAsterisk As New Label()
-
- ' Set their properties
- lblAsterisk.Text = " * "
- btnEval.Text = " = "
- txtResult.ReadOnly = True
-
- ' this is necessary to achieve syntactically correct ID properties.
- txtFirst.ID = txtFirst.ClientID
- txtSecond.ID = txtSecond.ClientID
- txtResult.ID = txtResult.ClientID
-
- ' Establish correct width for text controls.
- AdjustControlWidth()
-
- ' Add to the controls collection.
- Controls.Add(txtFirst)
- Controls.Add(lblAsterisk)
- Controls.Add(txtSecond)
- Controls.Add(btnEval)
- Controls.Add(txtResult)
- End Sub
-
- <Browsable(False)> _
- Property Result() As Double
- Get
- EnsureChildControls()
- Try
- Return CDbl(txtResult.Text)
- Catch
- Return 0
- End Try
- End Get
- Set(ByVal Value As Double)
- EnsureChildControls()
- txtResult.Text = Value.ToString
- End Set
- End Property
-
- Protected Overrides Sub Render(ByVal output As System.Web.UI.HtmlTextWriter)
- ' Ensure the child controls exist and then render them.
- EnsureChildControls()
- RenderChildren(output)
- ' Adjust their width.
- AdjustControlWidth()
- End Sub
-
- ' Adjust controls' width.
- Private Sub AdjustControlWidth()
- ' Evaluate the space available for the three textboxes.
- Dim w As Unit = Unit.Pixel(CInt(Me.Width.Value - 50) \ 3)
- txtFirst.Width = w
- txtSecond.Width = w
- txtResult.Width = w
- End Sub
-
- Private Sub btnEval_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnEval.Click
- EnsureChildControls()
- Try
- Dim res As Double = CDbl(txtFirst.Text) * CDbl(txtSecond.Text)
- txtResult.Text = res.ToString
- Catch
- txtResult.Text = "# ERR #"
- End Try
- End Sub
-
- ' this nested class inherits from Button, but overrides its Render method
-
- Friend Class Button
- Inherits System.Web.UI.WebControls.Button
-
- ' this is where we do the magic
-
- Protected Overrides Sub Render(ByVal writer As System.Web.UI.HtmlTextWriter)
- ' If client scripts are disabled then render as usual and exit.
- If Not IsClientScriptEnabled() Then
- MyBase.Render(writer)
- Exit Sub
- End If
-
- ' Get a reference to the parent control.
- Dim parCtrl As MultiplierEx = DirectCast(Me.Parent, MultiplierEx)
-
- ' prepare the code that invokes the script
- Dim scriptInvoke As String = String.Format("javascript:MultiplierExecute({0},{1},{2});", _
- parCtrl.txtFirst.ClientID, parCtrl.txtSecond.ClientID, parCtrl.txtResult.ClientID)
-
- ' output the standard attributes.
- writer.AddAttribute("type", "button")
- writer.AddAttribute("name", Me.ClientID)
- writer.AddAttribute("value", Me.Text)
- ' output the onClick attribute.
- writer.AddAttribute("onClick", scriptInvoke)
-
- ' enclose attributes in <input> tag.
- writer.RenderBeginTag("input")
- writer.RenderEndTag()
- End Sub
-
- ' we output the JavaScript code in the OnPreRender method
-
- Protected Overrides Sub OnPreRender(ByVal e As System.EventArgs)
- ' Nothing to do if client scripts are disabled.
- If Not IsClientScriptEnabled() Then Exit Sub
-
- ' Prepare the script routine.
- Dim s As String
- s &= "<script language=""javascript""><!--{0}" & ControlChars.CrLf
- s &= "function MultiplierExecute(txt1, txt2, txt3) {" & ControlChars.CrLf
- s &= " var op1 = parseFloat( txt1.value );" & ControlChars.CrLf
- s &= " var op2 = parseFloat( txt2.value );" & ControlChars.CrLf
- s &= " txt3.value = (op1 * op2).toString(); " & ControlChars.CrLf
- s &= " }" & ControlChars.CrLf
- s &= "--></script>" & ControlChars.CrLf
- ' register the script on the page.
- Page.RegisterClientScriptBlock("MultiplierExecute", s)
-
- End Sub
-
- ' Return True if client script support is requested and possible.
- ' this routine can be easily reused in other applications
-
- Private Function IsClientScriptEnabled() As Boolean
- ' we need a Try block because accessing the Browser
- ' property at design time may throw
- Try
- ' Return False if DOM version is too low.
- If Page.Request.Browser.W3CDomVersion.Major < 1 Then
- Return False
- End If
-
- ' Return False if EcmaScript version is too low.
- If Page.Request.Browser.EcmaScriptVersion.CompareTo(New Version(1, 2)) < 0 Then
- Return False
- End If
-
- ' if all tests passed, return the EnableClientScript property of its parent
- Dim parCtrl As MultiplierEx = DirectCast(Me.Parent, MultiplierEx)
- IsClientScriptEnabled = parCtrl.EnableClientScript
- Catch
- ' return False if any error occurs
- Return False
- End Try
- End Function
-
- End Class
-
- End Class
-
-